package org.xukai.rest.common;
import static org.xukai.rest.common.RespCode.SUCCESS;
import static org.xukai.rest.common.RespCode.EXCEPTION;
import static org.xukai.rest.common.RespCode.INVALID_ARGS;
/**
 * @author xukai
 * @desc
 * @date 2016-12-29-下午 6:16
 */
public class ResponseUtil {

    /**
     * 无参私有构造函数
     */
    private ResponseUtil() {
        super();
    }

    /**
     * 响应成功
     *
     * @param <T> 泛型
     */
    public static <T> Response<T> success() {
        return new Response<T>(SUCCESS.code(), SUCCESS.message());
    }

    /**
     * 响应成功
     *
     * @param <T> 泛型
     */
    public static <T> Response<T> success(T data) {
        return new Response<T>(SUCCESS.code(), SUCCESS.message(), data);
    }

    /**
     * 处理发生异常
     *
     * @param <T> 泛型
     */
    public static <T> Response<T> exception() {
        return new Response<T>(EXCEPTION.code(), EXCEPTION.message());
    }

    /**
     * 处理发生异常
     *
     * @param <T> 泛型
     */
    public static <T> Response<T> exception(String message) {
        return new Response<T>(EXCEPTION.code(), message);
    }

    /**
     * 返回带异常信息的响应结果
     *
     * @param throwable 异常
     */
    public static <T> Response<T> exception(Throwable throwable) {
        return new Response<T>(EXCEPTION.code(), EXCEPTION.message(), EXCEPTION.getClass().getName(),
                getStackTrace(throwable));
    }

    /**
     * 处理参数验证失效
     *
     * @param <T> 泛型
     */
    public static <T> Response<T> invalid(String message) {
        return new Response<T>(INVALID_ARGS.code(), message);
    }

    /**
     * 通用响应结果
     *
     * @param code    响应码
     * @param message 消息
     * @param <T>     泛型
     */
    public static <T> Response<T> response(int code, String message) {
        return new Response<T>(code, message);
    }

    /**
     * 通用响应结果
     *
     * @param respCode 响应码
     * @param <T>      泛型
     */
    public static <T> Response<T> response(RespCode respCode) {
        return new Response<T>(respCode.code(), respCode.message());
    }

    /**
     * 通用响应结果
     *
     * @param respCode 响应码
     * @param data     结果
     * @param <T>      泛型
     */
    public static <T> Response<T> response(RespCode respCode, T data) {
        return new Response<T>(respCode.code(), respCode.message(), data);
    }

    /**
     * 通用响应结果
     *
     * @param respCode 响应码
     * @param message  返回消息
     * @param data     结果
     * @param <T>      泛型
     */
    public static <T> Response<T> response(RespCode respCode, String message, T data) {
        return new Response<T>(respCode.code(), message, data);
    }

    /**
     * 获得异常的stack信息
     *
     * @param throwable 异常
     * @return string型的异常stack信息
     */
    private static String getStackTrace(Throwable throwable) {
        if (throwable == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        Throwable cause = throwable;
        StackTraceElement[] trace;
        for (int i = 0; i < 10 && cause != null; i++) {
            trace = throwable.getStackTrace();
            for (int j = 0; j < trace.length; j++) {
                sb.append("\tat " + trace[j] + "\n");
            }
            cause = throwable.getCause();
        }
        return sb.toString();
    }
}
